package com.lin.generator.service;

import com.google.common.base.CaseFormat;
import com.lin.generator.model.Field;
import com.lin.generator.model.Table;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author 猴哥
 */
public abstract class AbstractService {
	/**
	 * 获取表信息
	 *
	 * @param dbName 数据库名
	 * @return 表信息
	 */
	abstract public List<Table> getTables(String dbName);

	/**
	 * 获取字段信息
	 *
	 * @param dbName 数据库名
	 * @param tableName 表名
	 * @return 字段信息
	 */
	abstract public List<Field> getFields(String dbName, String tableName);

	/**
	 * 获取表数据
	 *
	 * @param dbName 数据库名称
	 * @param removePrefixes 去除的前缀
	 * @param generatorTables 要生成的表
	 * @param typeMap 类型映射
	 * @return 表数据
	 */
	public List<Table> getTables(String dbName, List<String> removePrefixes, List<String> generatorTables, Map<String, List<String>> typeMap) {
		// 获取表数据
		List<Table> tableList = this.getTables(dbName);
		// 获取字段数据
		tableList.forEach(table -> {
			table.setFieldList(this.getFields(dbName, table.getTableName()));
		});

		// 转换驼峰
		return toCamel(tableList, removePrefixes, generatorTables, typeMap);
	}

	/**
	 * 转换驼峰
	 *
	 * @param tableList 表
	 * @param removePrefixes 去除的前缀
	 * @param generatorTables 要生成的表
	 * @param typeMap 类型映射
	 * @return 转换后的结果
	 */
	protected List<Table> toCamel(List<Table> tableList, List<String> removePrefixes, List<String> generatorTables, Map<String, List<String>> typeMap) {
		// 转换表格
		return tableList.stream()
				// 过滤要生成的表
				.filter(table -> {
					if (!CollectionUtils.isEmpty(generatorTables)) {
						return generatorTables.stream().map(String::toUpperCase).collect(Collectors.toList()).contains(table.getTableName().toUpperCase());
					}
					return true;
				})
				.peek(table -> {
					// 去除前缀的表名
					String tableName = table.getTableName();
					if (!CollectionUtils.isEmpty(removePrefixes)) {
						for (String prefix : removePrefixes) {
							if (tableName.startsWith(prefix)) {
								tableName = tableName.replaceFirst("^" + prefix, "");
							}
						}
					}

					// 小驼峰
					table.setLowerCamel(CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, tableName));
					// 大驼峰
					table.setUpperCamel(CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, tableName));
					if (CollectionUtils.isEmpty(table.getFieldList())) {
						return;
					}

					// 转换字段
					List<Field> fieldList = table.getFieldList()
							.stream()
							.peek(field -> {
								// 小驼峰
								field.setLowerCamel(CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, field.getFieldName()));
								// 大驼峰
								field.setUpperCamel(CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, field.getFieldName()));
								// 获取Java类型
								typeMap.forEach((javaType, regexList) -> {
									// 遍历正则
									for (String regex : regexList) {
										Pattern pattern = Pattern.compile(regex);
										Matcher matcher = pattern.matcher(field.getJdbcType());
										// 如果匹配到正则
										if (matcher.find()) {
											field.setJavaType(javaType);
											break;
										}
									}
								});
							})
							.collect(Collectors.toList());
					table.setFieldList(fieldList);
				})
				.collect(Collectors.toList());
	}
}
